#include <head.h>

// 定义停车场的容量
#define PARKING_LOT_SIZE 5

// 定义停车位状态数组
int parkingLot[PARKING_LOT_SIZE];

// 定义信号量
sem_t semaphore;

// 定义互斥锁
pthread_mutex_t mutex;

// 初始化停车位状态
void initializeParkingLot()
{
    for (int i = 0; i < PARKING_LOT_SIZE; i++)
    {
        parkingLot[i] = 0;
    }
}

// 打印停车位状态
void printParkingLotStatus()
{
    printf("停车场状态：");
    for (int i = 0; i < PARKING_LOT_SIZE; i++)
    {
        printf("%d ", parkingLot[i]);
    }
    printf("\n");
}

// 车辆进入停车场
void vehicleEnterParkingLot()
{
    // 等待信号量
    sem_wait(&semaphore);

    // 加锁
    pthread_mutex_lock(&mutex);

    // 查找空位
    int emptySlot = -1;
    for (int i = 0; i < PARKING_LOT_SIZE; i++)
    {
        if (parkingLot[i] == 0)
        {
            emptySlot = i;
            break;
        }
    }

    // 如果有空位，将车辆停入
    if (emptySlot != -1)
    {
        parkingLot[emptySlot] = 1;
        printf("车辆进入停车场，停在 %d 号停车位\n", emptySlot);
    }
    else
    {
        printf("停车场已满，车辆无法进入\n");
    }

    // 解锁
    pthread_mutex_unlock(&mutex);

    // 释放信号量
    sem_post(&semaphore);
}

// 车辆离开停车场
void vehicleExitParkingLot()
{
    // 等待信号量
    sem_wait(&semaphore);

    // 加锁
    pthread_mutex_lock(&mutex);

    // 查找已停车辆的停车位
    int occupiedSlot = -1;
    for (int i = 0; i < PARKING_LOT_SIZE; i++)
    {
        if (parkingLot[i] == 1)
        {
            occupiedSlot = i;
            break;
        }
    }

    // 如果有已停车辆，将其驶出
    if (occupiedSlot != -1)
    {
        parkingLot[occupiedSlot] = 0;
        printf("车辆离开停车场，%d 号停车位空出\n", occupiedSlot);
    }
    else
    {
        printf("停车场内没有车辆\n");
    }

    // 解锁
    pthread_mutex_unlock(&mutex);

    // 释放信号量
    sem_post(&semaphore);
}

// 停车场管理员线程
void *parkingLotAdministrator(void *arg)
{
    while (1)
    {
        // 监控停车场状态
        printf("停车场管理员：");
        printParkingLotStatus();

        // 等待一段时间
        sleep(2);
    }
    return NULL;
}

int main(int argc, char const *argv[])
{
    // 初始化信号量和互斥锁
    sem_init(&semaphore, 0, PARKING_LOT_SIZE);
    pthread_mutex_init(&mutex, NULL);

    // 初始化停车位状态
    initializeParkingLot();

    // 创建停车场管理员线程
    pthread_t adminThread;
    pthread_create(&adminThread, NULL, parkingLotAdministrator, NULL);

    // 模拟车辆进入和离开停车场
    vehicleEnterParkingLot();
    vehicleEnterParkingLot();
    vehicleExitParkingLot();
    vehicleEnterParkingLot();
    vehicleEnterParkingLot();
    vehicleExitParkingLot();
    vehicleEnterParkingLot();
    vehicleEnterParkingLot();
    vehicleEnterParkingLot();
    vehicleEnterParkingLot();

    // 等待停车场管理员线程结束
    pthread_join(adminThread, NULL);

    // 销毁信号量和互斥锁
    sem_destroy(&semaphore);
    pthread_mutex_destroy(&mutex);

    return 0;
}
